import { TouchHandle } from "../../../../core/data_ext";
import SerializeAble, { Serialize, SerializeClass } from "../../../../core/serialize";
import { SubjectComponent } from "../../../../core/subject";
import SubBody, { SubBodyEventContact, SubBodyEventType } from "../../../box2d_utils/sub_body";
import MutiTouch from "../../../some_good_prefab/assets/muti_touch";

const { ccclass, property } = cc._decorator;

@SerializeClass("PlayerData")
export class PlayerData extends SerializeAble {
    @Serialize()
    health = 5;
};

const SPEED = 1000;
@ccclass
export default class PlayerArea extends SubjectComponent {
    @property(cc.Label)
    lbScore: cc.Label = null;
    @property(SubBody)
    door: SubBody = null;
    @property(SubBody)
    handle: SubBody = null;
    mt: MutiTouch = null;
    playerData: PlayerData;
    onLoad() {
        this.mt = this.addComponent(MutiTouch);
        this.mt.on("start", this.onTouchStart, this);
        this.mt.on("move", this.onTouchMove, this);

        this.door.on(SubBodyEventContact, this.ballIn, this);
    }
    init(playerData: PlayerData) {
        this.playerData = playerData;
        this.refresh();
    }
    refresh() {
        this.lbScore.string = `${this.playerData.health}`;
    }
    ballIn(evt: SubBodyEventContact) {
        if (evt.type !== SubBodyEventType.Begin) {
            return;
        }

        if (evt.self.tag === 3 && evt.other.node.name == "ball") {
            this.emit("ball-in");

            this.playerData.health--;
            if (this.playerData.health <= 0) {
                this.emit("dead");
            }

            this.refresh();
        }
    }

    onTouchStart(touch: TouchHandle) {
        let np = this.node.convertToNodeSpaceAR(touch.loc);
        cc.Tween.stopAllByTarget(this.handle.node);
        let dis = cc.v2(this.handle.node.position).sub(np).len();
        if (dis < 10) {
            this.handle.node.setPosition(np);
        }
        else {
            cc.tween(this.handle.node).to(dis / SPEED, { x: np.x, y: np.y }, { easing: "cubicOut" }).start();
        }
    }
    onTouchMove(touch: TouchHandle) {
        this.handle.node.x += touch.delta.x;
        this.handle.node.y += touch.delta.y;
    }

    protected lateUpdate(dt: number): void {
        if (this.handle.node.x + this.handle.node.width / 2 > this.node.width / 2) {
            this.handle.node.x = this.node.width / 2 - this.handle.node.width / 2;
        }
        else if (this.handle.node.x - this.handle.node.width / 2 < -this.node.width / 2) {
            this.handle.node.x = -this.node.width / 2 + this.handle.node.width / 2;
        }

        if (this.handle.node.y + this.handle.node.height / 2 > this.node.height / 2) {
            this.handle.node.y = this.node.height / 2 - this.handle.node.height / 2;
        }
        else if (this.handle.node.y - this.handle.node.height / 2 < -this.node.height / 2) {
            this.handle.node.y = -this.node.height / 2 + this.handle.node.height / 2;
        }
    }

    setDoorSize(size: number) {
        let borderSize = (this.node.width - size) / 2;

        this.door.node.width = size;
        let col = this.door.getComponent(cc.PhysicsBoxCollider);
        col.size.width = size;
        col.apply();

        let cols = this.node.getComponentsInChildren(cc.PhysicsBoxCollider);
        {
            cols[1].offset.x = -size / 2 - borderSize / 2;
            cols[1].size.width = borderSize;
            cols[1].apply();
        }
        {
            cols[2].offset.x = size / 2 + borderSize / 2;
            cols[2].size.width = borderSize;
            cols[2].apply();
        }
    }

    setHandleSize(size: number) {
        this.handle.node.width = size;
        this.handle.node.height = size;
        let col = this.handle.getComponent(cc.PhysicsCircleCollider);
        col.radius = size / 2;
        col.apply();
    }
};